home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Tools / MABuildTool.p < prev    next >
Text File  |  1991-05-01  |  56KB  |  2,135 lines

  1. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
  2. {------------------------------------------------------------------------------
  3.  
  4. FILE MABuildTool.p
  5.  Copyright © 1986-1991 Apple Computer, Inc.  All rights reserved.
  6.  
  7. NAME
  8.  MABuild -- process MABuild options
  9.  
  10. SYNOPSIS
  11.  MABuild
  12.  
  13. DESCRIPTION
  14. ------------------------------------------------------------------------------}
  15. PROGRAM MABuild;
  16.  
  17.     USES Types, MacAppTypes,
  18.         {}
  19.          Memory, UPascalObject, UObject,
  20.  
  21.         { • Building Blocks }
  22.          UPascalTool,
  23.  
  24.         { • Implementation use }
  25.          UFailure, UList, UAssociation, TextEdit, OSUtils, Editions,UMacAppUtilities,
  26.          CursorCtl, Signal, PasLibIntf, IntEnv, ToolUtils, Packages;
  27.  
  28.     CONST
  29.         { Keyword IDs }
  30.         kwAsm                = 1;
  31.         kwC                 = 2;
  32.         kwCPlus             = 3;
  33.         kwLib                = 4;
  34.         kwLink                = 5;
  35.         kwMake                = 6;
  36.         kwPascal            = 7;
  37.         kwRez                = 8;
  38.         kwCreatorAndBundle            = 9;
  39.         kwd                 = 10;
  40.         kwRenameFlag        = 11;
  41.         kwPP                = 12;
  42.         kwNoPP                = 13;
  43.         kwTT                = 14;
  44.         kwNoTT                = 15;
  45.         kwAlign             = 16;
  46.         kwNoAlign            = 17;
  47.         kwSeparateObjects    = 18;
  48.         kwNoSeparateObjects = 19;
  49.         kwExecute            = 20;
  50.         kwNoExecute         = 21;
  51.         kwFail                = 22;
  52.         kwNoFail            = 23;
  53.         kwLinkMap            = 24;
  54.         kwNoLinkMap         = 25;
  55.         kwLinkXRef            = 26;
  56.         kwNoLinkXRef        = 27;
  57.         kwAutoBuild         = 28;
  58.         kwNoAutoBuild        = 29;
  59.         kwUserAutoBuild     = 30;
  60.         kwNoUserAutoBuild    = 31;
  61.         kwMacApp            = 32;
  62.         kwNoMacApp            = 33;
  63.         kwDebugTheDebugger    = 34;
  64.         kwNoDebugTheDebugger = 35;
  65.         kwDebug             = 36;
  66.         kwNoDebug            = 37;
  67.         kwBottleNeck        = 38;
  68.         kwNoBottleNeck        = 39;
  69.         kwExpandEnvVars     = 40;
  70.         kwNoExpandEnvVars    = 41;
  71.         kwSave                = 42;
  72.         kwNoSave            = 43;
  73.         kwRun                = 44;
  74.         kwNoRun             = 45;
  75.         kwInspector         = 47;
  76.         kwNoInspector        = 48;
  77.         kwUnInit            = 49;
  78.         kwNoUnInit            = 50;
  79.         kwRangeCheck        = 51;
  80.         kwNoRangeCheck        = 52;
  81.         kwNames             = 53;
  82.         kwNoNames            = 54;
  83.         kwSym                = 55;
  84.         kwNoSym             = 56;
  85.         kwTrace             = 57;
  86.         kwNoTrace            = 58;
  87.         kwNeedsColorQD        = 61;
  88.         kwNoNeedsColorQD    = 62;
  89.         kwPerform            = 63;
  90.         kwNoPerform         = 64;
  91.         kwNeedsSystem7        = 65;
  92.         kwNoNeedsSystem7    = 66;
  93.         kwNeedsMC68020        = 68;
  94.         kwNoNeedsMC68020    = 69;
  95.         kwNeedsMC68030        = 70;
  96.         kwNoNeedsMC68030    = 71;
  97.         kwNeedsFPU            = 72;
  98.         kwNoNeedsFPU        = 73;
  99.         kwTemplateViews     = 76;
  100.         kwNoTemplateViews    = 77;
  101.         kwStatusOnly        = 80;
  102.         kwNoStatusOnly        = 81;
  103.         kwE                 = 82;
  104.         kwR                 = 83;
  105.         kwS                 = 84;
  106.  
  107.         kwMALibrary         = 85;
  108.         kwNoMALibrary        = 86;
  109.  
  110.         kwCPlusSupport        = 87;
  111.         kwNoCPlusSupport    = 88;
  112.  
  113.         kwExperimentalAndUnsupported = 89;
  114.         kwNoExperimentalAndUnsupported = 90;
  115.  
  116.         kwPasLoad            = 91;
  117.         kwNoPasLoad         = 92;
  118.  
  119.         kwCPlusLoad         = 93;
  120.         kwNoCPlusLoad        = 94;
  121.  
  122.         kwModelFarCode        = 95;
  123.         kwNoModelFarCode    = 96;
  124.  
  125.         kwModelFarData        = 97;
  126.         kwNoModelFarData    = 98;
  127.         
  128.         kwDebugMsg        = 99;
  129.         kwNoDebugMsg        = 100;
  130.  
  131.         kHelpStr            = 129;                        { Resource ID of the stringlist printed for
  132.                                                          help }
  133.  
  134.     TYPE
  135.         TextPtr             = ^TEXT;
  136.  
  137.         TStringHandle        = OBJECT (TObject)
  138.             fHandle:            Handle;
  139.             PROCEDURE TStringHandle.WriteToFile(theFile: TextPtr);
  140.             PROCEDURE TStringHandle.Catenate(theString: Str255);
  141.             PROCEDURE TStringHandle.CatenateToFront(theString: Str255);
  142.             PROCEDURE TStringHandle.IStringHandle;
  143.             FUNCTION TStringHandle.AsStr255: Str255;
  144.             PROCEDURE TStringHandle.Free; OVERRIDE;
  145.             END;
  146.  
  147.         TMABuildTool        = OBJECT (TPascalTool)
  148.             fMacApp:            Boolean;
  149.  
  150.             fDebugTheDebugger:    Boolean;
  151.             fDebug:             Boolean;
  152.             fDebugMsg:            Boolean;
  153.             fInspector:         Boolean;
  154.             fNames:             Boolean;
  155.             fRangeCheck:        Boolean;
  156.             fPerform:            Boolean;
  157.             fSym:                Boolean;
  158.             fTrace:             Boolean;
  159.             fUnInit:            Boolean;
  160.             fAlign:             Boolean;
  161.             fSeparateObjects:    Boolean;
  162.             fSeparateObjectsFolder: Str255;
  163.             fMALibrary:         Boolean;
  164.             fPasLoad:            Boolean;                { Make Pascal's symbol table dumps external
  165.                                                          files instead of the default of using the
  166.                                                          source file's resource fork }
  167.             fCPlusLoad:         Boolean;                { Create load/dump files for C++ }
  168.  
  169.             fCPlusSupport:        Boolean;
  170.             fExperimentalAndUnsupported: Boolean;        { True if the user want to flirt with
  171.                                                          certain destruction }
  172.             fModelFarCode:        Boolean;
  173.             fModelFarData:        Boolean;
  174.             fNeedsColorQD:        Boolean;
  175.             fNeedsMC68020:        Boolean;
  176.             fNeedsMC68030:        Boolean;
  177.             fNeedsFPU:            Boolean;
  178.             fNeedsSystem7:        Boolean;
  179.             fTemplateViews:     Boolean;
  180.  
  181.             fAllProgress:        Boolean;
  182.             fExecute:            Boolean;
  183.             fAutoBuild:         Boolean;
  184.             fUserAutoBuild:     Boolean;
  185.             fNoFail:            Boolean;
  186.             fLinkMap:            Boolean;
  187.             fLinkXRef:            Boolean;
  188.             fStatusOnly:        Boolean;
  189.             fTimes:             Boolean;
  190.             fRunAfterBuild:     Boolean;
  191.             fSaveBeforeBuild:    Boolean;
  192.             fBottleNeckedDispatching: Boolean;
  193.             fExpandEnvironmentVars: Boolean;
  194.  
  195.             fEverExported:        Boolean;                { only need to export once }
  196.  
  197.             { The following is split out from other compiler options because UMacAppUniversal.cp
  198.               must be compiled to run on 68000 machines. The CPlus compiler does not have compiler
  199.               directives to control machine options. It can only be controlled from the command
  200.               line. }
  201.  
  202.             fCPlusCPUOptions:    TStringHandle;
  203.             fPascalCPUOptions:    TStringHandle;
  204.             
  205.             fAsmOptions:        TStringHandle;
  206.             fCOptions:            TStringHandle;
  207.             fCPlusOptions:        TStringHandle;
  208.             fEchoOptions:        TStringHandle;
  209.             fLibOptions:        TStringHandle;
  210.             fLinkOptions:        TStringHandle;
  211.             fMakeOptions:        TStringHandle;
  212.             fPascalOptions:     TStringHandle;
  213.             fRezOptions:        TStringHandle;
  214.             fCreatorAndBundleOptions:    TStringHandle;
  215.  
  216.             fTargStringList:    TList;
  217.             fOptionFlags:        TStringHandle;
  218.  
  219.             fOutputFile:        TextPtr;
  220.  
  221.             fStartPath:            Str255;
  222.  
  223.             fRenameFlagsPairs:    TAssociation;
  224.  
  225.             PROCEDURE TMABuildTool.IMABuildTool;
  226.  
  227.             PROCEDURE TMABuildTool.DoProcessFileArg(arg: Str255); OVERRIDE;
  228.             PROCEDURE TMABuildTool.DoProcessOptionArg(kw: integer); OVERRIDE;
  229.             PROCEDURE TMABuildTool.DoShowUsage; OVERRIDE;
  230.             PROCEDURE TMABuildTool.DoStartProgress; OVERRIDE;
  231.             PROCEDURE TMABuildTool.DoToolAction; OVERRIDE;
  232.             PROCEDURE TMABuildTool.DoAllTargets;
  233.             PROCEDURE TMABuildTool.InstallKeyWords; OVERRIDE;
  234.             PROCEDURE TMABuildTool.EachSourceToolOptionStringDo(PROCEDURE
  235.                                                                 DoToOptionString(itsStringHandle:
  236.                                                                                  TStringHandle));
  237.             PROCEDURE TMABuildTool.CatenateToSourceOptionStrings(newText: Str255);
  238.             PROCEDURE TMABuildTool.Echo(aStr: Str255);
  239.             PROCEDURE TMABuildTool.Execute(aStr: Str255);
  240.             PROCEDURE TMABuildTool.SetIE(theVariable: Str255;
  241.                                          theValue: Str255); { output a set instruction }
  242.             FUNCTION TMABuildTool.Exists(theFile: Str255): Boolean;
  243.             END;
  244.  
  245.     VAR
  246.         gMABuildTool:        TMABuildTool;                { The tool }
  247.         gDirectorySeparator: Str255;                    { : or / as required by host filesystem }
  248.  
  249. {--------------------------------------------------------------------------------------------------}
  250. {$S TRes}
  251.  
  252.     FUNCTION NewTStringHandle: TStringHandle;
  253.  
  254.         VAR
  255.             aTStringHandle:     TStringHandle;
  256.  
  257.         BEGIN
  258.         New(aTStringHandle);
  259.         aTStringHandle.IStringHandle;
  260.         NewTStringHandle := aTStringHandle;
  261.         END;
  262.  
  263. {--------------------------------------------------------------------------------------------------}
  264. {$S TRes}
  265.  
  266.     PROCEDURE TStringHandle.WriteToFile(theFile: TextPtr);
  267.  
  268.         VAR
  269.             remaining:            integer;
  270.             aString:            Str255;
  271.             thisTime, offset:    integer;
  272.  
  273.         BEGIN
  274.         remaining := GetHandleSize(fHandle);
  275.         offset := 0;
  276.         WHILE remaining > 0 DO
  277.             BEGIN
  278.             IF remaining > 255 THEN
  279.                 thisTime := 255
  280.             ELSE
  281.                 thisTime := remaining;
  282.             remaining := remaining - thisTime;
  283.             BlockMove(Ptr(ord(fHandle^) + offset), Ptr(@aString[1]), thisTime);
  284.             offset := offset + thisTime;
  285.             aString[0] := chr(thisTime);
  286.             Write(theFile^, aString);
  287.             END;
  288.         END;
  289.  
  290. {--------------------------------------------------------------------------------------------------}
  291. {$S TRes}
  292.  
  293.     FUNCTION TStringHandle.AsStr255: Str255;
  294.  
  295.         VAR
  296.             aString:            Str255;
  297.  
  298.         BEGIN
  299.         aString[0] := chr(min(GetHandleSize(fHandle), 255));
  300.         BlockMove(fHandle^, Ptr(@aString[1]), length(aString));
  301.         AsStr255 := aString;
  302.         END;
  303.  
  304. {--------------------------------------------------------------------------------------------------}
  305. {$S TRes}
  306.  
  307.     PROCEDURE TStringHandle.IStringHandle;
  308.  
  309.         VAR
  310.             aHandle:            Handle;
  311.  
  312.         BEGIN
  313.         fHandle := NIL;
  314.         aHandle := NewHandle(0);
  315.         FailNil(aHandle);
  316.         fHandle := aHandle;
  317.         END;
  318.  
  319. {--------------------------------------------------------------------------------------------------}
  320. {$S TRes}
  321.  
  322.     PROCEDURE TStringHandle.Free;
  323.  
  324.         BEGIN
  325.         fHandle := DisposeIfHandle(fHandle);
  326.         inherited Free;
  327.         END;
  328.  
  329. {--------------------------------------------------------------------------------------------------}
  330. {$S TRes}
  331.  
  332.     PROCEDURE TStringHandle.Catenate(theString: Str255);
  333.  
  334.         VAR
  335.             aLong:                Longint;
  336.  
  337.         BEGIN
  338.         aLong := Munger(fHandle, GetHandleSize(fHandle), NIL, 0, { force insertion }
  339.                         Ptr(@theString[1]), length(theString));
  340.         FailMemError;
  341.         END;
  342.  
  343. {--------------------------------------------------------------------------------------------------}
  344. {$S TRes}
  345.  
  346.     PROCEDURE TStringHandle.CatenateToFront(theString: Str255);
  347.  
  348.         VAR
  349.             aLong:                Longint;
  350.  
  351.         BEGIN
  352.         aLong := Munger(fHandle, 0, NIL, 0,             { force insertion }
  353.                         Ptr(@theString[1]), length(theString));
  354.         FailMemError;
  355.         END;
  356.  
  357. {--------------------------------------------------------------------------------------------------}
  358. {$S TRes}
  359.  
  360.     PROCEDURE TMABuildTool.DoShowUsage;
  361.  
  362.         VAR
  363.             theHelpString:        Str255;
  364.             i:                    integer;
  365.  
  366.         BEGIN
  367.         PLFlush(diagnostic);
  368.         PLSetVBuf(diagnostic, NIL, _IOFBF, 4096);
  369.  
  370.         { output each string in the stringlist }
  371.         i := 1;
  372.         GetIndString(theHelpString, kHelpStr, i);
  373.         WHILE (theHelpString <> '') DO
  374.             BEGIN
  375.             WriteLn(diagnostic, theHelpString);
  376.             i := succ(i);
  377.             GetIndString(theHelpString, kHelpStr, i);
  378.             END;
  379.         END;
  380.  
  381. {--------------------------------------------------------------------------------------------------}
  382. {$S TInit}
  383.  
  384.     PROCEDURE TMABuildTool.DoProcessFileArg(arg: Str255);
  385.  
  386.         VAR
  387.             aStringHandle:        TStringHandle;
  388.  
  389.         BEGIN
  390.         { Special case for MacApp as target for backward compatibility (until post 2.0)}
  391.         IF EqualString(arg, 'MacApp', FALSE, TRUE) THEN
  392.             fAutoBuild := TRUE
  393.         ELSE
  394.             BEGIN
  395.             aStringHandle := NewTStringHandle;
  396.             aStringHandle.Catenate(arg);
  397.             fTargStringList.InsertLast(aStringHandle);
  398.             END;
  399.         END;
  400.  
  401. {--------------------------------------------------------------------------------------------------}
  402. {$S TInit}
  403.  
  404.     PROCEDURE TMABuildTool.DoStartProgress;
  405.  
  406.         VAR
  407.             theDateTimeString:    Str255;
  408.  
  409.         BEGIN
  410.         IUTimeString(fStartDateTime, TRUE, theDateTimeString);
  411.         Write(diagnostic, gProgName, ' - v. 3.0a2 Release ', compdate, '          Start: ',
  412.               theDateTimeString);
  413.  
  414.         IUDateString(fStartDateTime, shortDate, theDateTimeString);
  415.         WriteLn(diagnostic, ' ', theDateTimeString);
  416.  
  417.         WriteLn(diagnostic);
  418.         WriteLn(diagnostic, 'Copyright Apple Computer, Inc. 1986-1991');
  419.         WriteLn(diagnostic, 'All Rights Reserved.');
  420.         WriteLn(diagnostic);
  421.         PLFlush(diagnostic);
  422.         END;
  423.  
  424. {--------------------------------------------------------------------------------------------------}
  425. {$S TRes}
  426.  
  427.     PROCEDURE TMABuildTool.EachSourceToolOptionStringDo(PROCEDURE
  428.                                                         DoToOptionString(itsStringHandle:
  429.                                                                          TStringHandle));
  430.  
  431.         BEGIN
  432.         DoToOptionString(fAsmOptions);
  433.         DoToOptionString(fCOptions);
  434.         DoToOptionString(fCPlusOptions);
  435.         DoToOptionString(fMakeOptions);
  436.         DoToOptionString(fPascalOptions);
  437.         DoToOptionString(fRezOptions);
  438.         END;
  439.  
  440. {--------------------------------------------------------------------------------------------------}
  441. {$S TRes}
  442.  
  443.     PROCEDURE TMABuildTool.CatenateToSourceOptionStrings(newText: Str255);
  444.  
  445.         PROCEDURE DoToOptionString(itsStringHandle: TStringHandle);
  446.  
  447.             BEGIN
  448.             itsStringHandle.Catenate(newText);
  449.             END;
  450.  
  451.         BEGIN
  452.         EachSourceToolOptionStringDo(DoToOptionString);
  453.         END;
  454.  
  455. {--------------------------------------------------------------------------------------------------}
  456. {$S TInit}
  457.  
  458.     PROCEDURE TMABuildTool.DoProcessOptionArg(kw: integer);
  459.  
  460.         VAR
  461.             theNextArg:         Str255;
  462.  
  463.         BEGIN
  464.         CASE kw OF
  465.             kwAsm:
  466.                 BEGIN
  467.                 fAsmOptions.Catenate(' ');
  468.                 fAsmOptions.Catenate(GetNextArg);
  469.                 END;
  470.  
  471.             kwC:
  472.                 BEGIN
  473.                 fCOptions.Catenate(' ');
  474.                 fCOptions.Catenate(GetNextArg);
  475.                 END;
  476.  
  477.             kwCPlus:
  478.                 BEGIN
  479.                 fCPlusOptions.Catenate(' ');
  480.                 fCPlusOptions.Catenate(GetNextArg);
  481.                 END;
  482.  
  483.             kwLib:
  484.                 BEGIN
  485.                 fLibOptions.Catenate(' ');
  486.                 fLibOptions.Catenate(GetNextArg);
  487.                 END;
  488.  
  489.             kwLink:
  490.                 BEGIN
  491.                 fLinkOptions.Catenate(' ');
  492.                 fLinkOptions.Catenate(GetNextArg);
  493.                 END;
  494.  
  495.             kwMake:
  496.                 BEGIN
  497.                 fMakeOptions.Catenate(' ');
  498.                 fMakeOptions.Catenate(GetNextArg);
  499.                 END;
  500.  
  501.             kwPascal:
  502.                 BEGIN
  503.                 fPascalOptions.Catenate(' ');
  504.                 fPascalOptions.Catenate(GetNextArg);
  505.                 END;
  506.  
  507.             kwRez:
  508.                 BEGIN
  509.                 fRezOptions.Catenate(' ');
  510.                 fRezOptions.Catenate(GetNextArg);
  511.                 END;
  512.  
  513.             kwCreatorAndBundle:
  514.                 BEGIN
  515.                 fCreatorAndBundleOptions.Catenate(' ');
  516.                 fCreatorAndBundleOptions.Catenate(GetNextArg);
  517.                 END;
  518.  
  519.             kwd:
  520.                 BEGIN
  521.                 theNextArg := GetNextArg;
  522.  
  523.                 fAsmOptions.Catenate(' -d ');
  524.                 fAsmOptions.Catenate(theNextArg);
  525.  
  526.                 fCOptions.Catenate(' -d ');
  527.                 fCOptions.Catenate(theNextArg);
  528.  
  529.                 fCPlusOptions.Catenate(' -d ');
  530.                 fCPlusOptions.Catenate(theNextArg);
  531.  
  532.                 fMakeOptions.Catenate(' -d ');
  533.                 fMakeOptions.Catenate(theNextArg);
  534.  
  535.                 fPascalOptions.Catenate(' -d ');
  536.                 fPascalOptions.Catenate(theNextArg);
  537.  
  538.                 fRezOptions.Catenate(' -d ');
  539.                 fRezOptions.Catenate(theNextArg);
  540.  
  541.                 END;
  542.  
  543.             kwRenameFlag:
  544.                 BEGIN
  545.                 fRenameFlagsPairs.InsertEntry(GetNextArg, GetNextArg);
  546.                 END;
  547.  
  548.             kwPP:
  549.                 BEGIN
  550.                 fAllProgress := TRUE;
  551.                 fProgress := TRUE;
  552.                 END;
  553.             kwNoPP:
  554.                 BEGIN
  555.                 fAllProgress := FALSE;
  556.                 fProgress := FALSE;
  557.                 END;
  558.  
  559.             kwTT:
  560.                 BEGIN
  561.                 fTimes := TRUE;
  562.                 fTime := TRUE;
  563.                 END;
  564.             kwNoTT:
  565.                 BEGIN
  566.                 fTimes := FALSE;
  567.                 fTime := FALSE;
  568.                 END;
  569.  
  570.             kwAlign:
  571.                 fAlign := TRUE;
  572.             kwNoAlign:
  573.                 fAlign := FALSE;
  574.  
  575.             kwSeparateObjects:
  576.                 fSeparateObjects := TRUE;
  577.             kwNoSeparateObjects:
  578.                 fSeparateObjects := FALSE;
  579.  
  580.             kwExecute:
  581.                 fExecute := TRUE;
  582.             kwNoExecute:
  583.                 fExecute := FALSE;
  584.  
  585.             kwFail:
  586.                 fNoFail := FALSE;
  587.             kwNoFail:
  588.                 fNoFail := TRUE;
  589.  
  590.             kwLinkMap:
  591.                 fLinkMap := TRUE;
  592.             kwNoLinkMap:
  593.                 fLinkMap := FALSE;
  594.  
  595.             kwLinkXRef:
  596.                 fLinkXRef := TRUE;
  597.             kwNoLinkXRef:
  598.                 fLinkXRef := FALSE;
  599.  
  600.             kwAutoBuild:
  601.                 fAutoBuild := TRUE;
  602.             kwNoAutoBuild:
  603.                 fAutoBuild := FALSE;
  604.  
  605.             kwUserAutoBuild:
  606.                 fUserAutoBuild := TRUE;
  607.             kwNoUserAutoBuild:
  608.                 fUserAutoBuild := FALSE;
  609.  
  610.             kwMacApp:
  611.                 fMacApp := TRUE;
  612.             kwNoMacApp:
  613.                 fMacApp := FALSE;
  614.  
  615.             kwDebugTheDebugger:
  616.                 fDebugTheDebugger := TRUE;
  617.             kwNoDebugTheDebugger:
  618.                 fDebugTheDebugger := FALSE;
  619.  
  620.             kwDebug:
  621.                 BEGIN
  622.                 fDebug := TRUE;
  623.                 fDebugMsg := TRUE;
  624.                 fInspector := TRUE;
  625.                 fUnInit := TRUE;
  626.                 fPerform := TRUE;
  627.                 fRangeCheck := TRUE;
  628.                 fTrace := TRUE;
  629.                 fNames := TRUE;
  630.                 fBottleNeckedDispatching := TRUE;
  631.                 END;
  632.             kwNoDebug:
  633.                 BEGIN
  634.                 fDebug := FALSE;
  635.                 fDebugMsg := FALSE;
  636.                 fInspector := FALSE;
  637.                 fUnInit := FALSE;
  638.                 fPerform := FALSE;
  639.                 fRangeCheck := FALSE;
  640.                 fTrace := FALSE;
  641.                 fNames := FALSE;
  642.                 fBottleNeckedDispatching := FALSE;
  643.                 END;
  644.                 
  645.             kwDebugMsg:
  646.                 fDebugMsg := TRUE;
  647.             kwNoDebugMsg:
  648.                 fDebugMsg := FALSE;
  649.  
  650.             kwBottleNeck:
  651.                 fBottleNeckedDispatching := TRUE;
  652.             kwNoBottleNeck:
  653.                 fBottleNeckedDispatching := FALSE;
  654.  
  655.             kwExpandEnvVars:
  656.                 fExpandEnvironmentVars := TRUE;
  657.             kwNoExpandEnvVars:
  658.                 fExpandEnvironmentVars := FALSE;
  659.  
  660.             kwSave:
  661.                 fSaveBeforeBuild := TRUE;
  662.             kwNoSave:
  663.                 fSaveBeforeBuild := FALSE;
  664.  
  665.             kwRun:
  666.                 fRunAfterBuild := TRUE;
  667.             kwNoRun:
  668.                 fRunAfterBuild := FALSE;
  669.  
  670.             kwInspector:
  671.                 fInspector := TRUE;
  672.             kwNoInspector:
  673.                 fInspector := FALSE;
  674.  
  675.             kwUnInit:
  676.                 fUnInit := TRUE;
  677.             kwNoUnInit:
  678.                 fUnInit := FALSE;
  679.  
  680.             kwRangeCheck:
  681.                 fRangeCheck := TRUE;
  682.             kwNoRangeCheck:
  683.                 fRangeCheck := FALSE;
  684.  
  685.             kwNames:
  686.                 fNames := TRUE;
  687.             kwNoNames:
  688.                 fNames := FALSE;
  689.  
  690.             kwSym:
  691.                 fSym := TRUE;
  692.             kwNoSym:
  693.                 fSym := FALSE;
  694.  
  695.             kwTrace:
  696.                 fTrace := TRUE;
  697.             kwNoTrace:
  698.                 fTrace := FALSE;
  699.  
  700.             kwNeedsColorQD:
  701.                 fNeedsColorQD := TRUE;
  702.             kwNoNeedsColorQD:
  703.                 fNeedsColorQD := FALSE;
  704.  
  705.             kwPerform:
  706.                 fPerform := TRUE;
  707.             kwNoPerform:
  708.                 fPerform := FALSE;
  709.  
  710.             kwNeedsSystem7:
  711.                 fNeedsSystem7 := TRUE;
  712.             kwNoNeedsSystem7:
  713.                 fNeedsSystem7 := FALSE;
  714.  
  715.             kwNeedsMC68020:
  716.                 fNeedsMC68020 := TRUE;
  717.             kwNoNeedsMC68020:
  718.                 fNeedsMC68020 := FALSE;
  719.  
  720.             kwNeedsMC68030:
  721.                 fNeedsMC68030 := TRUE;
  722.             kwNoNeedsMC68030:
  723.                 fNeedsMC68030 := FALSE;
  724.  
  725.             kwNeedsFPU:
  726.                 fNeedsFPU := TRUE;
  727.             kwNoNeedsFPU:
  728.                 fNeedsFPU := FALSE;
  729.  
  730.             kwTemplateViews:
  731.                 fTemplateViews := TRUE;
  732.             kwNoTemplateViews:
  733.                 fTemplateViews := FALSE;
  734.  
  735.             kwStatusOnly:
  736.                 BEGIN
  737.                 fExecute := FALSE;
  738.                 fStatusOnly := TRUE;
  739.                 END;
  740.             kwNoStatusOnly:
  741.                 BEGIN
  742.                 fExecute := TRUE;
  743.                 fStatusOnly := FALSE;
  744.                 END;
  745.  
  746.             kwE:
  747.                 fMakeOptions.Catenate(' -e');
  748.  
  749.             kwR:
  750.                 BEGIN
  751.                 fExecute := FALSE;
  752.                 fStatusOnly := TRUE;
  753.                 fMakeOptions.Catenate(' -r');
  754.                 END;
  755.  
  756.             kwS:
  757.                 BEGIN
  758.                 fExecute := FALSE;
  759.                 fStatusOnly := TRUE;
  760.                 fMakeOptions.Catenate(' -s');
  761.                 END;
  762.  
  763.             kwMALibrary:
  764.                 BEGIN
  765.                 fMALibrary := TRUE;
  766.                 END;
  767.  
  768.             kwNoMALibrary:
  769.                 BEGIN
  770.                 fMALibrary := FALSE;
  771.                 END;
  772.  
  773.             kwPasLoad:
  774.                 BEGIN
  775.                 fPasLoad := TRUE;
  776.                 END;
  777.  
  778.             kwNoPasLoad:
  779.                 BEGIN
  780.                 fPasLoad := FALSE;
  781.                 END;
  782.  
  783.             kwCPlusLoad:
  784.                 BEGIN
  785.                 fCPlusLoad := TRUE;
  786.                 END;
  787.  
  788.             kwNoCPlusLoad:
  789.                 BEGIN
  790.                 fCPlusLoad := FALSE;
  791.                 END;
  792.  
  793.             kwCPlusSupport:
  794.                 BEGIN
  795.                 fCPlusSupport := TRUE;
  796.                 END;
  797.  
  798.             kwNoCPlusSupport:
  799.                 BEGIN
  800.                 fCPlusSupport := FALSE;
  801.                 END;
  802.  
  803.             kwExperimentalAndUnsupported:
  804.                 BEGIN
  805.                 fExperimentalAndUnsupported := TRUE;
  806.                 END;
  807.  
  808.             kwNoExperimentalAndUnsupported:
  809.                 BEGIN
  810.                 fExperimentalAndUnsupported := FALSE;
  811.                 END;
  812.  
  813.             kwModelFarCode:
  814.                 BEGIN
  815.                 fModelFarCode := TRUE;
  816.                 END;
  817.  
  818.             kwNoModelFarCode:
  819.                 BEGIN
  820.                 fModelFarCode := FALSE;
  821.                 END;
  822.  
  823.             kwModelFarData:
  824.                 BEGIN
  825.                 fModelFarData := TRUE;
  826.         END;
  827.  
  828.             kwNoModelFarData:
  829.                 BEGIN
  830.                 fModelFarData := FALSE;
  831.         END;
  832.  
  833.             OTHERWISE
  834.                 inherited DoProcessOptionArg(kw);
  835.         END;
  836.  
  837.         END;
  838.  
  839. {--------------------------------------------------------------------------------------------------}
  840. {$S TInit}
  841.  
  842.     PROCEDURE TMABuildTool.IMABuildTool;
  843.  
  844.         VAR
  845.             anAssociation:        TAssociation;
  846.             aString:            Str255;
  847.  
  848.         BEGIN
  849.         IPascalTool;
  850.  
  851.         { Try to get the appropriate separator character for directories }
  852.         IF IEGetEnv('MADirectorySeparator', aString) THEN
  853.             gDirectorySeparator := aString
  854.         ELSE
  855.             gDirectorySeparator := ':';
  856.  
  857.         fOutputFile := @Output;
  858.         PLFlush(fOutputFile^);
  859.         PLSetVBuf(fOutputFile^, NIL, _IOFBF, 8192);
  860.  
  861.         fRenameFlagsPairs := NIL;
  862.         New(anAssociation);
  863.         anAssociation.IAssociation;
  864.         fRenameFlagsPairs := anAssociation;
  865.  
  866.         { setup the default options }
  867.         fMacApp := TRUE;
  868.  
  869.         fDebugTheDebugger := FALSE;
  870.  
  871.         fDebug := FALSE;
  872.         fDebugMsg := FALSE;
  873.         fInspector := FALSE;
  874.         fNames := FALSE;
  875.         fPerform := FALSE;
  876.         fRangeCheck := FALSE;
  877.         fSym := FALSE;
  878.         fTrace := FALSE;
  879.         fUnInit := FALSE;
  880.         fAlign := TRUE;
  881.         fSeparateObjects := TRUE;
  882.         fSeparateObjectsFolder := '';
  883.         fMALibrary := TRUE;
  884.  
  885.         fPasLoad := FALSE;
  886.         fCPlusLoad := FALSE;
  887.  
  888.         fCPlusSupport := FALSE;
  889.         fExperimentalAndUnsupported := FALSE;
  890.         fModelFarCode := FALSE;
  891.         fModelFarData := FALSE;
  892.  
  893.         fNeedsColorQD := FALSE;
  894.         fNeedsMC68020 := FALSE;
  895.         fNeedsMC68030 := FALSE;
  896.         fNeedsFPU := FALSE;
  897.         fNeedsSystem7 := FALSE;
  898.         fTemplateViews := TRUE;
  899.  
  900.         fAllProgress := FALSE;
  901.         fExecute := TRUE;
  902.         fAutoBuild := FALSE;
  903.         fUserAutoBuild := TRUE;
  904.         fNoFail := FALSE;
  905.         fProgress := FALSE;
  906.         fStatusOnly := FALSE;
  907.         fTimes := FALSE;
  908.         fLinkMap := FALSE;
  909.         fLinkXRef := FALSE;
  910.         fBottleNeckedDispatching := FALSE;
  911.         fRunAfterBuild := FALSE;
  912.         fSaveBeforeBuild := FALSE;
  913.         fExpandEnvironmentVars := FALSE;
  914.  
  915.         fEverExported := FALSE;
  916.  
  917.         fCPlusCPUOptions := NIL;
  918.         fPascalCPUOptions := NIL;
  919.         fAsmOptions := NIL;
  920.         fCOptions := NIL;
  921.         fCPlusOptions := NIL;
  922.         fEchoOptions := NIL;
  923.         fLibOptions := NIL;
  924.         fLinkOptions := NIL;
  925.         fMakeOptions := NIL;
  926.         fPascalOptions := NIL;
  927.         fRezOptions := NIL;
  928.         fCreatorAndBundleOptions := NIL;
  929.  
  930.         fCPlusCPUOptions := NewTStringHandle;
  931.         fPascalCPUOptions := NewTStringHandle;
  932.         fAsmOptions := NewTStringHandle;
  933.         fCOptions := NewTStringHandle;
  934.         fCPlusOptions := NewTStringHandle;
  935.         fEchoOptions := NewTStringHandle;
  936.         fLibOptions := NewTStringHandle;
  937.         fLinkOptions := NewTStringHandle;
  938.         fMakeOptions := NewTStringHandle;
  939.         fPascalOptions := NewTStringHandle;
  940.         fRezOptions := NewTStringHandle;
  941.         fCreatorAndBundleOptions := NewTStringHandle;
  942.  
  943.         fEchoOptions := NIL;
  944.         fTargStringList := NIL;
  945.         fOptionFlags := NIL;
  946.  
  947.         fEchoOptions := NewTStringHandle;
  948.  
  949.         fTargStringList := NewList;
  950.  
  951.         fOptionFlags := NewTStringHandle;
  952.  
  953.         END;
  954.  
  955. {--------------------------------------------------------------------------------------------------}
  956. {$S TInit}
  957.  
  958.     PROCEDURE TMABuildTool.InstallKeyWords;
  959.  
  960.         BEGIN
  961.         inherited InstallKeyWords;
  962.  
  963.         InstallKeyWord('Asm', kwAsm);
  964.         InstallKeyWord('C', kwC);
  965.         InstallKeyWord('CPlus', kwCPlus);
  966.         InstallKeyWord('Lib', kwLib);
  967.         InstallKeyWord('Link', kwLink);
  968.         InstallKeyWord('Make', kwMake);
  969.         InstallKeyWord('Pascal', kwPascal);
  970.         InstallKeyWord('Rez', kwRez);
  971.         InstallKeyWord('CreatorAndBundle', kwCreatorAndBundle);
  972.         InstallKeyWord('d', kwd);
  973.         InstallKeyWord('RenameFlag', kwRenameFlag);
  974.         InstallKeyWord('PP', kwPP);
  975.         InstallKeyWord('NoPP', kwNoPP);
  976.         InstallKeyWord('TT', kwTT);
  977.         InstallKeyWord('NoTT', kwNoTT);
  978.         InstallKeyWord('Align', kwAlign);
  979.         InstallKeyWord('NoAlign', kwNoAlign);
  980.         InstallKeyWord('SeparateObjects', kwSeparateObjects);
  981.         InstallKeyWord('NoSeparateObjects', kwNoSeparateObjects);
  982.         InstallKeyWord('Execute', kwExecute);
  983.         InstallKeyWord('NoExecute', kwNoExecute);
  984.         InstallKeyWord('Fail', kwFail);
  985.         InstallKeyWord('NoFail', kwNoFail);
  986.         InstallKeyWord('LinkMap', kwLinkMap);
  987.         InstallKeyWord('NoLinkMap', kwNoLinkMap);
  988.         InstallKeyWord('LinkXRef', kwLinkXRef);
  989.         InstallKeyWord('NoLinkXRef', kwNoLinkXRef);
  990.         InstallKeyWord('AutoBuild', kwAutoBuild);
  991.         InstallKeyWord('NoAutoBuild', kwNoAutoBuild);
  992.         InstallKeyWord('UserAutoBuild', kwUserAutoBuild);
  993.         InstallKeyWord('NoUserAutoBuild', kwNoUserAutoBuild);
  994.         InstallKeyWord('MacApp', kwMacApp);
  995.         InstallKeyWord('NoMacApp', kwNoMacApp);
  996.         InstallKeyWord('DebugTheDebugger', kwDebugTheDebugger);
  997.         InstallKeyWord('NoDebugTheDebugger', kwNoDebugTheDebugger);
  998.         InstallKeyWord('Debug', kwDebug);
  999.         InstallKeyWord('NoDebug', kwNoDebug);
  1000.         InstallKeyWord('DebugMsg', kwDebugMsg);
  1001.         InstallKeyWord('NoDebugMsg', kwNoDebugMsg);
  1002.         InstallKeyWord('BottleNeck', kwBottleNeck);
  1003.         InstallKeyWord('NoBottleNeck', kwNoBottleNeck);
  1004.         InstallKeyWord('ExpandEnvVars', kwExpandEnvVars);
  1005.         InstallKeyWord('NoExpandEnvVars', kwNoExpandEnvVars);
  1006.         InstallKeyWord('Save', kwSave);
  1007.         InstallKeyWord('NoSave', kwNoSave);
  1008.         InstallKeyWord('Run', kwRun);
  1009.         InstallKeyWord('NoRun', kwNoRun);
  1010.         InstallKeyWord('Inspector', kwInspector);
  1011.         InstallKeyWord('NoInspector', kwNoInspector);
  1012.         InstallKeyWord('UnInit', kwUnInit);
  1013.         InstallKeyWord('NoUnInit', kwNoUnInit);
  1014.         InstallKeyWord('RangeCheck', kwRangeCheck);
  1015.         InstallKeyWord('NoRangeCheck', kwNoRangeCheck);
  1016.         InstallKeyWord('Names', kwNames);
  1017.         InstallKeyWord('NoNames', kwNoNames);
  1018.         InstallKeyWord('Sym', kwSym);
  1019.         InstallKeyWord('NoSym', kwNoSym);
  1020.         InstallKeyWord('Trace', kwTrace);
  1021.         InstallKeyWord('NoTrace', kwNoTrace);
  1022.         InstallKeyWord('NeedsColorQD', kwNeedsColorQD);
  1023.         InstallKeyWord('NoNeedsColorQD', kwNoNeedsColorQD);
  1024.         InstallKeyWord('Perform', kwPerform);
  1025.         InstallKeyWord('NoPerform', kwNoPerform);
  1026.         InstallKeyWord('NeedsSystem7', kwNeedsSystem7);
  1027.         InstallKeyWord('NoNeedsSystem7', kwNoNeedsSystem7);
  1028.         InstallKeyWord('NeedsMC68020', kwNeedsMC68020);
  1029.         InstallKeyWord('NoNeedsMC68020', kwNoNeedsMC68020);
  1030.         InstallKeyWord('NeedsMC68030', kwNeedsMC68030);
  1031.         InstallKeyWord('NoNeedsMC68030', kwNoNeedsMC68030);
  1032.         InstallKeyWord('NeedsFPU', kwNeedsFPU);
  1033.         InstallKeyWord('NoNeedsFPU', kwNoNeedsFPU);
  1034.         InstallKeyWord('TemplateViews', kwTemplateViews);
  1035.         InstallKeyWord('NoTemplateViews', kwNoTemplateViews);
  1036.         InstallKeyWord('StatusOnly', kwStatusOnly);
  1037.         InstallKeyWord('NoStatusOnly', kwNoStatusOnly);
  1038.         InstallKeyWord('E', kwE);
  1039.         InstallKeyWord('R', kwR);
  1040.         InstallKeyWord('S', kwS);
  1041.         InstallKeyWord('PasLoad', kwPasLoad);
  1042.         InstallKeyWord('NoPasLoad', kwNoPasLoad);
  1043.  
  1044.         InstallKeyWord('CPlusLoad', kwCPlusLoad);
  1045.         InstallKeyWord('NoCPlusLoad', kwNoCPlusLoad);
  1046.  
  1047.         InstallKeyWord('MALibrary', kwMALibrary);
  1048.         InstallKeyWord('NoMALibrary', kwNoMALibrary);
  1049.  
  1050.         InstallKeyWord('CPlusSupport', kwCPlusSupport);
  1051.         InstallKeyWord('NoCPlusSupport', kwNoCPlusSupport);
  1052.  
  1053.         InstallKeyWord('ExperimentalAndUnsupported', kwExperimentalAndUnsupported);
  1054.         InstallKeyWord('NoExperimentalAndUnsupported', kwNoExperimentalAndUnsupported);
  1055.  
  1056.         InstallKeyWord('ModelFarCode', kwModelFarCode);
  1057.         InstallKeyWord('NoModelFarCode', kwNoModelFarCode);
  1058.  
  1059.         InstallKeyWord('ModelFarData', kwModelFarData);
  1060.         InstallKeyWord('NoModelFarData', kwNoModelFarData);
  1061.  
  1062.         END;
  1063.  
  1064. {--------------------------------------------------------------------------------------------------}
  1065. {$S TRes}
  1066.  
  1067.     PROCEDURE TMABuildTool.Execute(aStr: Str255);
  1068.  
  1069.         BEGIN
  1070.         WriteLn(fOutputFile^, aStr);
  1071.         END;
  1072.  
  1073. {--------------------------------------------------------------------------------------------------}
  1074. {$S TRes}
  1075.  
  1076.     PROCEDURE TMABuildTool.SetIE(theVariable: Str255;
  1077.                                  theValue: Str255);
  1078.  
  1079.         BEGIN
  1080.         WriteLn(fOutputFile^, 'SET ', theVariable, ' "', theValue, '"');
  1081.         END;
  1082.  
  1083. {--------------------------------------------------------------------------------------------------}
  1084. {$S TRes}
  1085.  
  1086.     PROCEDURE TMABuildTool.Echo(aStr: Str255);
  1087.  
  1088.         BEGIN
  1089.         Write(fOutputFile^, '{MAEcho} ');
  1090.         WriteLn(fOutputFile^, aStr);
  1091.         END;
  1092.  
  1093. {--------------------------------------------------------------------------------------------------}
  1094. {$S TRes}
  1095.  
  1096.     FUNCTION TMABuildTool.Exists(theFile: Str255): Boolean;
  1097.     { Return true if the file or directory exists }
  1098.  
  1099.         VAR
  1100.             fndrInfo:            FInfo;
  1101.             aCInfoPBRec:        CInfoPBRec;
  1102.  
  1103.         BEGIN
  1104.         WITH aCInfoPBRec DO
  1105.             BEGIN
  1106.             ioCompletion := NIL;
  1107.             ioNamePtr := @theFile;
  1108.             ioVRefNum := 0;
  1109.             ioFRefNum := 0;
  1110.             ioFDirIndex := 0;
  1111.             ioDirID := 0;
  1112.             END;
  1113.  
  1114.         Exists := (PBGetCatInfo(@aCInfoPBRec, FALSE) = noErr) & (aCInfoPBRec.IOResult = noErr);
  1115.         END;
  1116.  
  1117. {--------------------------------------------------------------------------------------------------}
  1118. {$S TRes}
  1119.  
  1120.     PROCEDURE TMABuildTool.DoAllTargets;
  1121.  
  1122.         VAR
  1123.             aTStringHandle:     TStringHandle;
  1124.             aString, bString, XAppPath, XAppName, MAMakeFileExtension, MASetupExtension: Str255;
  1125.             ObjApp, SrcApp, SeparateObjectsFolder, BuildFlags, MABuildFlagsExtension: Str255;
  1126.             i:                    integer;
  1127.             automake, autorez, anyPascal, anyCPlus: Boolean;
  1128.             dirID:                Longint;
  1129.             MAShellVersion:     Str255;
  1130.  
  1131.         BEGIN
  1132.         { Process every target in fTargStringList }
  1133.         aTStringHandle := TStringHandle(fTargStringList.First);
  1134.  
  1135.         WHILE aTStringHandle <> NIL DO
  1136.             BEGIN
  1137.             fTargStringList.Delete(aTStringHandle);
  1138.  
  1139.             aString := aTStringHandle.AsStr255;         { Paths can't currently be longer than this
  1140.                                                          anyways! (MPW 3.1)}
  1141.  
  1142.             aTStringHandle.Free;
  1143.  
  1144.             { find the pathname and filename }
  1145.             XAppName := aString;
  1146.             XAppPath := '';
  1147.             FOR i := length(aString) DOWNTO 1 DO
  1148.                 BEGIN
  1149.                 IF Copy(aString, i, length(gDirectorySeparator)) = gDirectorySeparator THEN
  1150.                     BEGIN
  1151.                     XAppName := Copy(aString, i + 1, length(aString) - i);
  1152.                     XAppPath := Copy(aString, 1, i);
  1153.                     LEAVE;
  1154.                     END
  1155.                 END;
  1156.  
  1157.             { Automatically trim .MAMake off the target name if it was specified }
  1158.             IF IEGetEnv('MAMakeFileExtension', MAMakeFileExtension) & (MAMakeFileExtension <>
  1159.                '') THEN
  1160.                 BEGIN
  1161.                 aString := MAMakeFileExtension;
  1162.                 bString := XAppName;
  1163.                 UprStr255(aString);
  1164.                 UprStr255(bString);
  1165.                 i := pos(aString, bString);
  1166.                 IF (i <> 0) & (i + length(MAMakeFileExtension) - 1 = length(XAppName)) THEN
  1167.                     Delete(XAppName, i, length(MAMakeFileExtension));
  1168.                 END;
  1169.  
  1170.             { Blank path is current path }
  1171.             IF XAppPath = '' THEN
  1172.                 XAppPath := fStartPath;
  1173.  
  1174.             SetIE('XAppPath', XAppPath);
  1175.             SetIE('XAppName', XAppName);
  1176.  
  1177.             { Check for the  MASetupExtension file }
  1178.             IF IEGetEnv('MASetupExtension', MASetupExtension) & Exists(concat(XAppPath, XAppName,
  1179.                                                                        MASetupExtension)) THEN
  1180.                 WriteLn(fOutputFile^, 'EXECUTE "', concat(XAppPath, XAppName, MASetupExtension),
  1181.                         '"');
  1182.  
  1183.             { Process separate objects into the source and object pathnames… }
  1184.             SeparateObjectsFolder := fSeparateObjectsFolder;
  1185.             ObjApp := concat(XAppPath, SeparateObjectsFolder);
  1186.             SrcApp := XAppPath;
  1187.             SetIE('ObjApp', ObjApp);
  1188.             SetIE('SrcApp', SrcApp);
  1189.  
  1190.             IF fProgress THEN
  1191.                 Echo('"Target Folder: ∂"{ObjApp}∂""');
  1192.  
  1193.             { Linkmap and LinkXref }
  1194.             IF fLinkMap THEN
  1195.                 BEGIN
  1196.                 IF fPerform THEN
  1197.                     SetIE('XLinkMap', '-la -lf -l > ∂''{ObjApp}{XAppName}.map∂'' ')
  1198.                 ELSE
  1199.                     SetIE('XLinkMap', '-la -lf -map > ∂''{ObjApp}{XAppName}.map∂'' ');
  1200.                 END
  1201.             ELSE
  1202.                 SetIE('XLinkMap', '');
  1203.  
  1204.             IF fLinkXRef THEN
  1205.                 SetIE('XLinkXRef', '-x ∂''{ObjApp}{XAppName}.xref∂'' ')
  1206.             ELSE
  1207.                 SetIE('XLinkXRef', '');
  1208.  
  1209.             { Get various file names for autodependencies }
  1210.             { in Pascal }
  1211.             anyPascal := FALSE;
  1212.             IF Exists(concat(SrcApp, 'U', XAppName, '.p')) THEN
  1213.                 BEGIN
  1214.                 anyPascal := TRUE;
  1215.                 SetIE('XUAppName.p', concat(SrcApp, 'U', XAppName, '.p'));
  1216.                 SetIE('XUAppName.p.o', concat(ObjApp, 'U', XAppName, '.p.o'));
  1217.                 END
  1218.             ELSE
  1219.                 BEGIN
  1220.                 SetIE('XUAppName.p', '');
  1221.                 SetIE('XUAppName.p.o', '');
  1222.                 END;
  1223.  
  1224.             IF Exists(concat(SrcApp, 'M', XAppName, '.p')) THEN
  1225.                 BEGIN
  1226.                 anyPascal := TRUE;
  1227.                 SetIE('XMAppName.p', concat(SrcApp, 'M', XAppName, '.p'));
  1228.                 SetIE('XMAppName.p.o', concat(ObjApp, 'M', XAppName, '.p.o'));
  1229.                 END
  1230.             ELSE
  1231.                 BEGIN
  1232.                 SetIE('XMAppName.p', '');
  1233.                 SetIE('XMAppName.p.o', '');
  1234.                 END;
  1235.  
  1236.             IF Exists(concat(SrcApp, XAppName, '.p')) THEN
  1237.                 BEGIN
  1238.                 anyPascal := TRUE;
  1239.                 SetIE('XAppName.p', concat(SrcApp, XAppName, '.p'));
  1240.                 SetIE('XAppName.p.o', concat(ObjApp, XAppName, '.p.o'));
  1241.                 END
  1242.             ELSE
  1243.                 BEGIN
  1244.                 SetIE('XAppName.p', '');
  1245.                 SetIE('XAppName.p.o', '');
  1246.                 END;
  1247.  
  1248.             { you should wonder at how long this next chunk took to write! }
  1249.             SetIE('EXIT', '0');
  1250.             SetIE('XUAppName.inc.p', '`(Files "{SrcApp}"U{XAppName}.≈.p) ≥ dev:null`');
  1251.             SetIE('EXIT', '1');
  1252.  
  1253.             { in C++ }
  1254.             anyCPlus := FALSE;
  1255.             IF Exists(concat(SrcApp, 'U', XAppName, '.h')) THEN
  1256.                 BEGIN
  1257.                 anyCPlus := TRUE;
  1258.                 fCPlusSupport := TRUE;
  1259.                 SetIE('XUAppName.h', concat(SrcApp, 'U', XAppName, '.h'));
  1260.                 END
  1261.             ELSE
  1262.                 BEGIN
  1263.                 SetIE('XUAppName.h', '');
  1264.                 END;
  1265.  
  1266.             IF Exists(concat(SrcApp, 'U', XAppName, '.cp')) THEN
  1267.                 BEGIN
  1268.                 anyCPlus := TRUE;
  1269.                 fCPlusSupport := TRUE;
  1270.                 SetIE('XUAppName.cp', concat(SrcApp, 'U', XAppName, '.cp'));
  1271.                 SetIE('XUAppName.cp.o', concat(ObjApp, 'U', XAppName, '.cp.o'));
  1272.                 END
  1273.             ELSE
  1274.                 BEGIN
  1275.                 SetIE('XUAppName.cp', '');
  1276.                 SetIE('XUAppName.cp.o', '');
  1277.                 END;
  1278.  
  1279.             IF Exists(concat(SrcApp, 'M', XAppName, '.cp')) THEN
  1280.                 BEGIN
  1281.                 anyCPlus := TRUE;
  1282.                 fCPlusSupport := TRUE;
  1283.                 SetIE('XMAppName.cp', concat(SrcApp, 'M', XAppName, '.cp'));
  1284.                 SetIE('XMAppName.cp.o', concat(ObjApp, 'M', XAppName, '.cp.o'));
  1285.                 END
  1286.             ELSE
  1287.                 BEGIN
  1288.                 SetIE('XMAppName.cp', '');
  1289.                 SetIE('XMAppName.cp.o', '');
  1290.                 END;
  1291.  
  1292.             IF Exists(concat(SrcApp, XAppName, '.cp')) THEN
  1293.                 BEGIN
  1294.                 anyCPlus := TRUE;
  1295.                 fCPlusSupport := TRUE;
  1296.                 SetIE('XAppName.cp', concat(SrcApp, XAppName, '.cp'));
  1297.                 SetIE('XAppName.cp.o', concat(ObjApp, XAppName, '.cp.o'));
  1298.                 END
  1299.             ELSE
  1300.                 BEGIN
  1301.                 SetIE('XAppName.cp', '');
  1302.                 SetIE('XAppName.cp.o', '');
  1303.                 END;
  1304.  
  1305.             { See if we can automake it }
  1306.             IF NOT Exists(concat(XAppPath, XAppName, MAMakeFileExtension)) THEN
  1307.                 BEGIN
  1308.                 automake := TRUE;
  1309.                 IF NOT (anyPascal | anyCPlus) THEN
  1310.                     BEGIN
  1311.                     Echo(
  1312. '''###'' MABuild: Bad parameter: Unable to access file: "{XAppPath}{XAppName}{MAMakeFileExtension}"'
  1313.                          );
  1314.                     Echo('MABuild of {XAppName} failed: `DATE`');
  1315.                     Execute('{MAFailed}');
  1316.  
  1317.                     IF fNoFail THEN
  1318.                         SetIE('XExitStatus', '1')
  1319.                     ELSE
  1320.                         Execute('EXIT 1');
  1321.                     END
  1322.                 END
  1323.             ELSE
  1324.                 automake := FALSE;
  1325.  
  1326.             { See if we can autorez it }
  1327.             IF NOT Exists(concat(XAppPath, XAppName, '.r')) THEN
  1328.                 BEGIN
  1329.                 autorez := TRUE;
  1330.                 SetIE('XAutoRez', '1');
  1331.                 SetIE('XAppRezSrc', '{MARIncludes}Default.r');
  1332.                 END
  1333.             ELSE
  1334.                 BEGIN
  1335.                 autorez := FALSE;
  1336.                 SetIE('XAutoRez', '0');
  1337.                 SetIE('XAppRezSrc', '{XAppPath}{XAppName}.r');
  1338.                 END;
  1339.  
  1340.             { Make sure separate objects folder exists }
  1341.             IF NOT Exists(ObjApp) & (DirCreate(0, 0, ObjApp, dirID) <> noErr) THEN
  1342.                 BEGIN
  1343.                 Echo('''###'' MABuild: Unable to create directory: "{ObjApp}"');
  1344.                 Echo('MABuild of {XAppName} failed: `DATE`');
  1345.                 Execute('{MAFailed}');
  1346.  
  1347.                 IF fNoFail THEN
  1348.                     SetIE('XRunStatus', '1')
  1349.                 ELSE
  1350.                     Execute('EXIT 1');
  1351.                 END;
  1352.  
  1353.             { SET the BuildFlags }
  1354.             IF IEGetEnv('MABuildFlagsExtension', MABuildFlagsExtension) THEN;
  1355.             BuildFlags := concat(ObjApp, XAppName, MABuildFlagsExtension);
  1356.             SetIE('BuildFlags', BuildFlags);
  1357.  
  1358.             { Find out what the last option flags were }
  1359.             IF Exists(BuildFlags) THEN
  1360.                 Execute('EXECUTE "{BuildFlags}" ∑ Dev:Null || SET Status 0')
  1361.             ELSE
  1362.                 SetIE('XLastOptionFlags', 'InvalidString');
  1363.  
  1364.             IF fExecute THEN
  1365.                 BEGIN
  1366.                 Execute('IF {XLastOptionFlags} != {XOptionFlags}');
  1367.              { the file BuildFlags will contain a SET command to set the value of XLastOptionFlags }
  1368.                 Echo('"SET XLastOptionFlags {XOptionFlags}"  >  "{BuildFlags}"');
  1369.                 Execute('END');
  1370.                 END;
  1371.  
  1372.             { Rebuild the application by creating the "MakeIt" file and then executing it }
  1373.             SetIE('XMakeIt', '{ObjApp}{XAppName}{MAMakeOutfileExtension}');
  1374.  
  1375. { SET the failure processing mode in the makeit files and (OPTIONALLY) the active environment vars into the makefile }
  1376.             IF fNoFail THEN
  1377.                 Echo('SET EXIT 0  > "{XMakeIt}"')
  1378.             ELSE
  1379.                 Echo('SET EXIT 1  > "{XMakeIt}"');
  1380.  
  1381.             IF fExpandEnvironmentVars THEN
  1382.                 BEGIN
  1383.                 IF fStatusOnly THEN
  1384.                     SetIE('XMakeitRedirection', '')
  1385.                 ELSE
  1386.                     SetIE('XMakeitRedirection', ' >> ∂''{XMakeIt}∂''');
  1387.  
  1388.                 Execute('SET AsmOptions {XMakeitRedirection}');
  1389.                 Execute('SET BuildFlags {XMakeitRedirection}');
  1390.                 Execute('SET COptions {XMakeitRedirection}');
  1391.                 Execute('SET CPlusOptions {XMakeitRedirection}');
  1392.                 Execute('SET CPlusCPUOptions {XMakeitRedirection}');
  1393.                 Execute('SET EchoOptions {XMakeitRedirection}');
  1394.                 Execute('SET LibOptions {XMakeitRedirection}');
  1395.                 Execute('SET LinkOptions {XMakeitRedirection}');
  1396.                 Execute('SET MakeOptions {XMakeitRedirection}');
  1397.                 Execute('SET ObjApp {XMakeitRedirection}');
  1398.                 Execute('SET PascalOptions {XMakeitRedirection}');
  1399.                 Execute('SET PascalCPUOptions {XMakeitRedirection}');
  1400.                 Execute('SET CreatorAndBundleOptions {XMakeitRedirection}');
  1401.                 Execute('SET RezOptions {XMakeitRedirection}');
  1402.                 Execute('SET SeparateObjectsFolder {XMakeitRedirection}');
  1403.                 Execute('SET SrcApp {XMakeitRedirection}');
  1404.                 Execute('SET XAppName {XMakeitRedirection}');
  1405.                 Execute('SET XAppName.cp {XMakeitRedirection}');
  1406.                 Execute('SET XAppName.cp.o {XMakeitRedirection}');
  1407.                 Execute('SET XAppName.p {XMakeitRedirection}');
  1408.                 Execute('SET XAppName.p.o {XMakeitRedirection}');
  1409.                 Execute('SET XAppRezSrc {XMakeitRedirection}');
  1410.                 Execute('SET XAutoRez {XMakeitRedirection}');
  1411.                 Execute('SET XLinkMap {XMakeitRedirection}');
  1412.                 Execute('SET XLinkXRef {XMakeitRedirection}');
  1413.                 Execute('SET XMAppName.cp {XMakeitRedirection}');
  1414.                 Execute('SET XMAppName.cp.o {XMakeitRedirection}');
  1415.                 Execute('SET XMAppName.p {XMakeitRedirection}');
  1416.                 Execute('SET XMAppName.p.o {XMakeitRedirection}');
  1417.                 Execute('SET XTimes {XMakeitRedirection}');
  1418.                 Execute('SET XRunAfterBuild {XMakeitRedirection}');
  1419.                 Execute('SET XUAppName.cp {XMakeitRedirection}');
  1420.                 Execute('SET XUAppName.cp.o {XMakeitRedirection}');
  1421.                 Execute('SET XUAppName.h {XMakeitRedirection}');
  1422.                 Execute('SET XUAppName.p {XMakeitRedirection}');
  1423.                 Execute('SET XUAppName.p.o {XMakeitRedirection}');
  1424.                 END;
  1425.  
  1426.             { Export the various and sundry environment variables }
  1427.             IF NOT fEverExported THEN
  1428.                 BEGIN
  1429.                 fEverExported := TRUE;                    { only need to export once }
  1430.                 Execute('EXPORT ∂');
  1431.                 Execute(
  1432.       'AsmOptions BuildFlags COptions CPlusCPUOptions CPlusOptions EchoOptions LibOptions LinkOptions MakeOptions ∂'
  1433.                         );
  1434.                 Execute(
  1435. 'ObjApp PascalCPUOptions PascalOptions CreatorAndBundleOptions RezOptions SeparateObjectsFolder SrcApp XAppName XAppName.cp XAppName.cp.o ∂'
  1436.                         );
  1437.                 Execute(
  1438.              'XAppName.p XAppName.p.o XAppRezSrc XAutoRez XLinkMap XLinkXRef XMakeit XMAppName.cp ∂'
  1439.                         );
  1440.                 Execute('XMAppName.cp.o XMAppName.p XMAppName.p.o XTimes XRunAfterBuild ∂');
  1441.                 Execute(
  1442.                  'XUAppName.cp XUAppName.cp.o XUAppName.h XUAppName.inc.p XUAppName.p XUAppName.p.o'
  1443.                         );
  1444.                 END;
  1445.  
  1446.             { Give user makefile processing status message }
  1447.             IF fProgress THEN
  1448.                 BEGIN
  1449.                 IF automake THEN
  1450.                     Echo('"AutoMaking:    {XAppName}"')
  1451.                 ELSE
  1452.                     Echo('"Making:        {XAppName}{MAMakeFileExtension}"');
  1453.                 END;
  1454.  
  1455.             IF fTimes THEN
  1456.                 SetIE('XMakeStartTime', '`DATE -n`');
  1457.             SetIE('EXIT', '0');
  1458.  
  1459.             { run make }
  1460.             Execute('{MAMake} {MakeOptions} ∂');
  1461.  
  1462.             { Automatically include the CPLus libraries
  1463.             and select the proper FPU support.    !!! this is so hinky! (but its better than making MacApp users suffer!) }
  1464.             IF fCPlusSupport THEN
  1465.                 BEGIN
  1466.                 { Eliminate Pascal support }
  1467.                 Execute('-d PascalNonFPUSANELib=  ∂');
  1468.                 Execute('-d PascalFPUSANELib=  ∂');
  1469.                 Execute('-d PascalSupport=  ∂');
  1470.  
  1471.                 { Check if newer MPW 3.2 support }
  1472.                 IF IEGetEnv('MAShellVersion', MAShellVersion) & ((Copy(MAShellVersion, 1, 3) <>
  1473.                    '3.0') & (Copy(MAShellVersion, 1, 3) <> '3.1')) THEN
  1474.                     BEGIN
  1475.                     { Eliminate 3.0, 3.1 CPlus Support }
  1476.                     Execute('-d 31CPlusNonFPUSANELib=  ∂');
  1477.                     Execute('-d 31CPlusFPUSANELib=  ∂');
  1478.                     Execute('-d 31CPlusSupport=  ∂');
  1479.  
  1480.                     { Select the proper floating point support }
  1481.                     IF fNeedsFPU THEN
  1482.                         Execute('-d CPlusNonFPUSANELib=  ∂')
  1483.                     ELSE
  1484.                         Execute('-d CPlusFPUSANELib=  ∂');
  1485.                     END
  1486.                 ELSE
  1487.                     BEGIN
  1488.                     { Eliminate 3.2 CPlus Support }
  1489.                     Execute('-d CPlusNonFPUSANELib=  ∂');
  1490.                     Execute('-d CPlusFPUSANELib=  ∂');
  1491.                     Execute('-d CPlusSupport=  ∂');
  1492.  
  1493.                     { Select the proper floating point support }
  1494.                     IF fNeedsFPU THEN
  1495.                         Execute('-d 31CPlusNonFPUSANELib=  ∂')
  1496.                     ELSE
  1497.                         Execute('-d 31CPlusFPUSANELib=  ∂');
  1498.                     END
  1499.                 END
  1500.             ELSE
  1501.                 BEGIN
  1502.                 { Eliminate CPlus support }
  1503.                 Execute('-d 31CPlusNonFPUSANELib=  ∂');
  1504.                 Execute('-d 31CPlusFPUSANELib=  ∂');
  1505.                 Execute('-d 31CPlusSupport=  ∂');
  1506.                 Execute('-d CPlusNonFPUSANELib=  ∂');
  1507.                 Execute('-d CPlusFPUSANELib=  ∂');
  1508.                 Execute('-d CPlusSupport=  ∂');
  1509.  
  1510.                 { Select the proper floating point support }
  1511.                 IF fNeedsFPU THEN
  1512.                     Execute('-d PascalNonFPUSANELib=  ∂')
  1513.                 ELSE
  1514.                     Execute('-d PascalFPUSANELib=  ∂');
  1515.                 END;
  1516.  
  1517.             { Select the proper link libraries for modelfar support by eliminating the definition of
  1518.             ModelFarSupport if it's not used }
  1519.             IF fModelFarCode | fModelFarData THEN
  1520.                 BEGIN
  1521.                 END
  1522.             ELSE
  1523.                 BEGIN
  1524.                 Execute('-d ModelFarSupport=  ∂');
  1525.                 END;
  1526.  
  1527.             IF automake THEN
  1528.                 Execute('-d AppName={XAppName} ∂');     { the default rules supply the rest }
  1529.             Execute('-f "{MATools}Basic Definitions" ∂');
  1530.             IF NOT automake THEN
  1531.                 Execute('-f "{XAppPath}{XAppName}{MAMakeFileExtension}" ∂'); { a makefile was
  1532.                 supplied }
  1533.             Execute('-f "{MATools}Build Rules and Dependencies" ∂');
  1534.             Execute('"{ObjApp}{XAppName}" ∂');
  1535.             IF NOT fStatusOnly THEN
  1536.                 Execute('>> "{XMakeIt}"')
  1537.             ELSE
  1538.                 Execute('');
  1539.  
  1540.             SetIE('XMakeStatus', '{Status}');
  1541.             SetIE('EXIT', '1');
  1542.             Execute('IF "{XMakeStatus}"');
  1543.             Echo('MAKE of {XAppName} failed: `DATE`');
  1544.             IF fTimes THEN
  1545.                 Echo('Elapsed time: `evaluate ∂`DATE -n∂` - {XMakeStartTime}` seconds');
  1546.             Execute('{MAFailed}');
  1547.             IF fNoFail THEN
  1548.                 SetIE('XExitStatus', '{XMakeStatus}')
  1549.             ELSE
  1550.                 Execute('EXIT "{XMakeStatus}"');
  1551.  
  1552.             IF fTimes THEN
  1553.                 BEGIN
  1554.                 Execute('ELSE');
  1555.                 Echo('Elapsed time: `evaluate ∂`DATE -n∂` - {XMakeStartTime}` seconds');
  1556.                 END;
  1557.             Execute('END');
  1558.  
  1559.             { Attempt Execution and let the user know how it all came out }
  1560.             IF fExecute THEN
  1561.                 BEGIN
  1562.                 SetIE('EXIT', '0');
  1563.                 Execute('"{XMakeIt}"');
  1564.                 SetIE('XRunStatus', '{Status}');
  1565.                 SetIE('EXIT', '1');
  1566.                 Execute('IF "{XRunStatus}"');
  1567.                 Execute('{MAFailed}');
  1568.                 IF fNoFail THEN
  1569.                     SetIE('XExitStatus', '{XRunStatus}')
  1570.                 ELSE
  1571.                     Execute('EXIT "{XRunStatus}"');
  1572.                 Execute('END');
  1573.                 END;
  1574.             aTStringHandle := TStringHandle(fTargStringList.First);
  1575.             END;
  1576.         END;
  1577.  
  1578. {--------------------------------------------------------------------------------------------------}
  1579. {$S TRes}
  1580.  
  1581.     PROCEDURE TMABuildTool.DoToolAction;
  1582.  
  1583.         VAR
  1584.             SeparateObjectsFolder, MASeparateObjectsPrefix: Str255;
  1585.             MAAutoBuild:        Str255;
  1586.             MAUserAutoBuild:    Str255;
  1587.             MAShortVersion:     Str255;
  1588.             MALoadFiles, LoadFileDir, CPlusLoad: Str255;
  1589.             aTStringHandle:     TStringHandle;
  1590.             aString:            Str255;
  1591.             dirID:                Longint;
  1592.             vRefNum:            integer;
  1593.             i: integer;
  1594.  
  1595.             {* PathNameFromDirID ********************************************************}
  1596.  
  1597.         FUNCTION PathNameFromDirID(dirID: Longint;
  1598.                                    vRefNum: integer): Str255;
  1599.  
  1600.             CONST
  1601.                 fsRtDir             = 2;
  1602.  
  1603.             VAR
  1604.                 Block:                CInfoPBRec;
  1605.                 directoryName, FullPathName: Str255;
  1606.                 err:                oserr;
  1607.  
  1608.             BEGIN
  1609.             FullPathName := '';
  1610.             WITH Block DO
  1611.                 BEGIN
  1612.                 ioNamePtr := @directoryName;
  1613.                 ioDrParID := dirID;
  1614.                 END;
  1615.  
  1616.             REPEAT
  1617.                 WITH Block DO
  1618.                     BEGIN
  1619.                     ioVRefNum := vRefNum;
  1620.                     ioFDirIndex := - 1;
  1621.                     ioDrDirID := Block.ioDrParID;
  1622.                     END;
  1623.                 err := PBGetCatInfo(@Block, FALSE);
  1624.  
  1625.                 IF gConfiguration.hasAUX THEN
  1626.                     BEGIN
  1627.                     IF directoryName[1] <> '/' THEN
  1628.                         BEGIN
  1629.                         { If this isn't root (i.e. "/"), append a slash ('/') }
  1630.                         directoryName := concat(directoryName, '/');
  1631.                         END;
  1632.                     END
  1633.                 ELSE
  1634.                     BEGIN
  1635.                     directoryName := concat(directoryName, ':');
  1636.                     END;
  1637.                 FullPathName := concat(directoryName, FullPathName);
  1638.             UNTIL (Block.ioDrDirID = fsRtDir);
  1639.  
  1640.             PathNameFromDirID := FullPathName;
  1641.             END;
  1642.  
  1643.         BEGIN
  1644.  
  1645.         IF NOT IEGetEnv('MAShortVersion', MAShortVersion) | (MAShortVersion <> '3.0a2') THEN
  1646.             BEGIN
  1647.             Stop(
  1648.            '''###'' MABuild: Whoops… You have not executed the Startup file in the MacApp directory'
  1649.                  );
  1650.             END;
  1651.         { Resolve matrix of options. }
  1652.         IF NOT fProgress THEN
  1653.             fEchoOptions.Catenate(' ∑ Dev:Null ');
  1654.         IF fDebug THEN
  1655.             fNames := TRUE;
  1656.  
  1657. {!!!!!#### still need parsing loops to process each of these as multiple targets if the var is a list }
  1658.         IF fUserAutoBuild & IEGetEnv('MAUserAutoBuild', MAUserAutoBuild) & (MAUserAutoBuild <>
  1659.            '') THEN
  1660.             BEGIN
  1661.             WHILE (length(MAUserAutoBuild) <> 0) DO
  1662.                 BEGIN
  1663.                 i := pos(',', MAUserAutoBuild);
  1664.                 IF i = 0 THEN
  1665.                     i := length(MAUserAutoBuild)
  1666.                 ELSE
  1667.                     i := i - 1;
  1668.                 aTStringHandle := NewTStringHandle;
  1669.                 aTStringHandle.Catenate(Copy(MAUserAutoBuild, 1, i));
  1670.                 fTargStringList.InsertFirst(aTStringHandle);
  1671.                 Delete(MAUserAutoBuild, 1, min(i + 1, length(MAUserAutoBuild))); { toss the target &
  1672.                     ,}
  1673.                 END;
  1674.             END;
  1675.  
  1676.         IF fAutoBuild & IEGetEnv('MAAutoBuild', MAAutoBuild) & (MAAutoBuild <> '') THEN
  1677.             BEGIN
  1678.             WHILE (length(MAAutoBuild) <> 0) DO
  1679.                 BEGIN
  1680.                 i := pos(',', MAAutoBuild);
  1681.                 IF i = 0 THEN
  1682.                     i := length(MAAutoBuild)
  1683.                 ELSE
  1684.                     i := i - 1;
  1685.                 aTStringHandle := NewTStringHandle;
  1686.                 aTStringHandle.Catenate(Copy(MAAutoBuild, 1, i));
  1687.                 fTargStringList.InsertFirst(aTStringHandle);
  1688.                 Delete(MAAutoBuild, 1, min(i + 1, length(MAAutoBuild))); { toss the target & ,}
  1689.                 END;
  1690.             END;
  1691.  
  1692.         { Building for use with MacApp? }
  1693.         IF fMacApp THEN
  1694.             CatenateToSourceOptionStrings(' -d qMacApp=TRUE')
  1695.         ELSE
  1696.             CatenateToSourceOptionStrings(' -d qMacApp=FALSE');
  1697.  
  1698.         IF fAlign THEN
  1699.             BEGIN
  1700.             fLinkOptions.Catenate(' -ac 4 -ad 4');
  1701.             fRezOptions.Catenate(' -align longword');
  1702.             END;
  1703.  
  1704.         { process elapsed time indication }
  1705.         IF fTimes THEN
  1706.             BEGIN
  1707.             fAsmOptions.Catenate(' -t');
  1708.             fCOptions.Catenate(' -t');
  1709.             fCPlusOptions.Catenate(' -t');
  1710.             { fLinkOptions.Catenate(' -t'); # -t means file type}
  1711.             { fLibOptions.Catenate(' -t'); # there isn't a -t option}
  1712.             { fMakeOptions.Catenate(' -t'); # -t means touch the files}
  1713.             fPascalOptions.Catenate(' -t');
  1714.             { fRezOptions.Catenate(' -t');     # -t means file type}
  1715.             fCreatorAndBundleOptions.Catenate(' -t');
  1716.             END;
  1717.  
  1718.         { Progress indication }
  1719.         IF fAllProgress THEN
  1720.             BEGIN
  1721.             CatenateToSourceOptionStrings(' -p');
  1722.             fLinkOptions.Catenate(' -p');
  1723.             fLibOptions.Catenate(' -p');
  1724.             fCreatorAndBundleOptions.Catenate(' -p');
  1725.             END;
  1726.  
  1727.         IF fBottleNeckedDispatching THEN
  1728.             fLinkOptions.Catenate(' -opt NoBypass')
  1729.         ELSE
  1730.             fLinkOptions.Catenate(' -opt on');
  1731.  
  1732.         { Debug the Debugger }
  1733.         IF fDebugTheDebugger THEN
  1734.             BEGIN
  1735.             fOptionFlags.Catenate('DD');
  1736.  
  1737.             CatenateToSourceOptionStrings(' -d qDebugTheDebugger=TRUE')
  1738.             END
  1739.         ELSE
  1740.             CatenateToSourceOptionStrings(' -d qDebugTheDebugger=FALSE');
  1741.  
  1742.         { PreSystem 7.0 support }
  1743.         IF fNeedsSystem7 THEN
  1744.             BEGIN
  1745.             fOptionFlags.Catenate('S7');
  1746.  
  1747.             CatenateToSourceOptionStrings(
  1748. ' -d qNeedsAppleEventMgr=TRUE -d qNeedsEditionMgr=TRUE -d qNeedsHelpMgr=TRUE -d qNeedsProcessMgr=TRUE -d qNeedsAliasMgr=TRUE -d qNeedsFolderMgr=TRUE -d qNeedsSystem7=TRUE -d SystemSevenOrLater=TRUE'
  1749.                                           );
  1750.             END
  1751.         ELSE
  1752.             CatenateToSourceOptionStrings(
  1753. ' -d qNeedsAppleEventMgr=FALSE -d qNeedsEditionMgr=FALSE -d qNeedsHelpMgr=FALSE -d qNeedsProcessMgr=FALSE -d qNeedsAliasMgr=FALSE -d qNeedsFolderMgr=FALSE -d qNeedsSystem7=FALSE -d SystemSevenOrLater=FALSE'
  1754.                                           );
  1755.  
  1756.         { ColorQD support }
  1757.         IF fNeedsColorQD THEN
  1758.             BEGIN
  1759.             fOptionFlags.Catenate('Cq');
  1760.  
  1761.             CatenateToSourceOptionStrings(' -d qNeedsColorQD=TRUE');
  1762.             END
  1763.         ELSE
  1764.             CatenateToSourceOptionStrings(' -d qNeedsColorQD=FALSE');
  1765.  
  1766.         { 020 support }
  1767.         IF fNeedsMC68020 THEN
  1768.             BEGIN
  1769.             fOptionFlags.Catenate('20');
  1770.  
  1771.             CatenateToSourceOptionStrings(' -d qNeedsMC68020=TRUE');
  1772.             fCPlusCPUOptions.Catenate(' -mc68020');
  1773.             fPascalCPUOptions.Catenate(' -mc68020');
  1774.             END
  1775.         ELSE
  1776.             CatenateToSourceOptionStrings(' -d qNeedsMC68020=FALSE');
  1777.  
  1778.         { 030 support }
  1779.         IF fNeedsMC68030 THEN
  1780.             BEGIN
  1781.             fOptionFlags.Catenate('30');
  1782.  
  1783.             CatenateToSourceOptionStrings(' -d qNeedsMC68030=TRUE');
  1784.             fCPlusCPUOptions.Catenate(' -mc68020');
  1785.             fPascalCPUOptions.Catenate(' -mc68020');
  1786.             END
  1787.         ELSE
  1788.             CatenateToSourceOptionStrings(' -d qNeedsMC68030=FALSE');
  1789.  
  1790.         { FPU support }
  1791.         IF fNeedsFPU THEN
  1792.             BEGIN
  1793.             fOptionFlags.Catenate('Fp');
  1794.  
  1795.             CatenateToSourceOptionStrings(' -d qNeedsFPU=TRUE');
  1796.             fCPlusCPUOptions.Catenate(' -mc68881 -elems881');
  1797.             fPascalCPUOptions.Catenate(' -mc68881 -d elems881=TRUE');
  1798.             END
  1799.         ELSE
  1800.             BEGIN
  1801.             CatenateToSourceOptionStrings(' -d qNeedsFPU=FALSE');
  1802.             END;
  1803.  
  1804.         { MacApp as library support }
  1805.         IF fMALibrary THEN
  1806.             BEGIN
  1807.             fMakeOptions.Catenate(' -d MacAppObjs=  ');
  1808.             END
  1809.         ELSE
  1810.             BEGIN
  1811.             fMakeOptions.Catenate(' -d MacAppLibrary=  ');
  1812.             END;
  1813.  
  1814.         { Pascal external symbol table files support }
  1815.         IF NOT fPasLoad THEN
  1816.             BEGIN
  1817.             fMakeOptions.Catenate(' -d PascalLoad=  -d PascalLoadOptions=  '); { Remove the
  1818.                 definitions }
  1819.             END;
  1820.  
  1821.         IF NOT fCPlusLoad THEN
  1822.             BEGIN
  1823.             fMakeOptions.Catenate(' -d CPlusLoad=  -d CPlusLoadObj=  -d CPlusLoadOptions=  '); { Remove the
  1824.                 definitions }
  1825.             END;
  1826.  
  1827.         { Embedded debugger names }
  1828.         IF fNames THEN
  1829.             BEGIN
  1830.             fOptionFlags.Catenate('Nm');
  1831.  
  1832.             CatenateToSourceOptionStrings(' -d qNames=TRUE');
  1833. {$IFC FALSE}                                            { !!! not until 32bit everything… gets too
  1834.                                                          big! }
  1835.             IF IEGetEnv('MAShellVersion', MAShellVersion) & (MAShellVersion <> '3.0a2') THEN
  1836.                 fLinkOptions.Catenate(' -opt names');    { Make the selector procs show up }
  1837. {$EndC}
  1838.             END
  1839.         ELSE
  1840.             BEGIN
  1841.             CatenateToSourceOptionStrings(' -d qNames=FALSE');
  1842.             fCOptions.Catenate(' -mbg off');
  1843.             fCPlusOptions.Catenate(' -mbg off');
  1844.             END;
  1845.  
  1846.         { Debugging support }
  1847.         IF fDebug THEN
  1848.             BEGIN
  1849.             fOptionFlags.Catenate('Db');
  1850.  
  1851.             CatenateToSourceOptionStrings(' -d qDebug=TRUE');
  1852.             fRezOptions.Catenate(' -d Debugging');        { For backward compatibility. To be dropped
  1853.                                                          in next release (post 2.0)}
  1854.             END
  1855.         ELSE
  1856.             BEGIN
  1857.             CatenateToSourceOptionStrings(' -d qDebug=FALSE');
  1858.             fMakeOptions.Catenate(' -d DebugFiles= -d DebugRsrcs= -d DebugLib=  '); { Eliminate
  1859.                 debug files as targets in the makefiles }
  1860.             END;
  1861.  
  1862.         { Debug messages support }
  1863.         IF fDebugMsg THEN
  1864.             BEGIN
  1865.             fOptionFlags.Catenate('Dm');
  1866.             CatenateToSourceOptionStrings(' -d qDebugMsg=TRUE');
  1867.             END
  1868.         ELSE
  1869.             BEGIN
  1870.             CatenateToSourceOptionStrings(' -d qDebugMsg=FALSE');
  1871.             END;
  1872.  
  1873.         { Inspector support }
  1874.         IF fInspector THEN
  1875.             BEGIN
  1876.             fOptionFlags.Catenate('In');
  1877.  
  1878.             CatenateToSourceOptionStrings(' -d qInspector=TRUE');
  1879.             END
  1880.         ELSE
  1881.             CatenateToSourceOptionStrings(' -d qInspector=FALSE');
  1882.  
  1883.         { UnInitialized storage support }
  1884.         IF fUnInit THEN
  1885.             BEGIN
  1886.             fOptionFlags.Catenate('Un');
  1887.  
  1888.             CatenateToSourceOptionStrings(' -d qUnInit=TRUE');
  1889.             END
  1890.         ELSE
  1891.             CatenateToSourceOptionStrings(' -d qUnInit=FALSE');
  1892.  
  1893.         { Perform support }
  1894.         IF fPerform THEN
  1895.             BEGIN
  1896.             fOptionFlags.Catenate('Pe');
  1897.  
  1898.             CatenateToSourceOptionStrings(' -d qPerform=TRUE');
  1899.             END
  1900.         ELSE
  1901.             BEGIN
  1902.             CatenateToSourceOptionStrings(' -d qPerform=FALSE');
  1903.             fMakeOptions.Catenate(' -d PerformLib= ');    { Eliminate the performance libraries as
  1904.                                                          target }
  1905.             END;
  1906.  
  1907.         { RangeCheck support }
  1908.         IF fRangeCheck THEN
  1909.             BEGIN
  1910.             fOptionFlags.Catenate('Ra');
  1911.  
  1912.             CatenateToSourceOptionStrings(' -d qRangeCheck=TRUE');
  1913.             END
  1914.         ELSE
  1915.             CatenateToSourceOptionStrings(' -d qRangeCheck=FALSE');
  1916.  
  1917.         { Trace support }
  1918.         IF fTrace THEN
  1919.             BEGIN
  1920.             fOptionFlags.Catenate('Tr');
  1921.  
  1922.             CatenateToSourceOptionStrings(' -d qTrace=TRUE');
  1923.             END
  1924.         ELSE
  1925.             CatenateToSourceOptionStrings(' -d qTrace=FALSE');
  1926.  
  1927.         { template views support }
  1928.         IF fTemplateViews THEN
  1929.             BEGIN
  1930.             fOptionFlags.Catenate('Te');
  1931.  
  1932.             CatenateToSourceOptionStrings(' -d qTemplateViews=TRUE');
  1933.             END
  1934.         ELSE
  1935.             CatenateToSourceOptionStrings(' -d qTemplateViews=FALSE');
  1936.  
  1937.         { symbolic debugging support }
  1938.         IF fSym THEN
  1939.             BEGIN
  1940.             fOptionFlags.Catenate('Sm');
  1941.  
  1942.             CatenateToSourceOptionStrings(' -d qSym=TRUE');
  1943.             fAsmOptions.Catenate(' -sym on');
  1944.             fCOptions.Catenate(' -sym on');
  1945.             fCPlusOptions.Catenate(' -sym on');
  1946.             fLinkOptions.Catenate(' -sym on');
  1947.             fPascalOptions.Catenate(' -sym on');
  1948.             END
  1949.         ELSE
  1950.             CatenateToSourceOptionStrings(' -d qSym=FALSE');
  1951.  
  1952.         { See if user wants to play with experimental and _UNSUPPORTED_ goodies. }
  1953.         IF fExperimentalAndUnsupported THEN
  1954.             BEGIN
  1955.             fOptionFlags.Catenate('Ex');
  1956.  
  1957.             CatenateToSourceOptionStrings(' -d qExperimentalAndUnsupported=TRUE');
  1958.             END
  1959.         ELSE
  1960.             CatenateToSourceOptionStrings(' -d qExperimentalAndUnsupported=FALSE');
  1961.  
  1962.         IF fModelFarCode THEN
  1963.             BEGIN
  1964.             fOptionFlags.Catenate('fC');
  1965.             fPascalOptions.Catenate(' -model farCode');
  1966.             fCOptions.Catenate(' -model farCode');
  1967.             fCPlusOptions.Catenate(' -model farCode');
  1968.  
  1969.             CatenateToSourceOptionStrings(' -d qModelFarCode=TRUE');
  1970.             END
  1971.         ELSE
  1972.             CatenateToSourceOptionStrings(' -d qModelFarCode=FALSE');
  1973.  
  1974.         IF fModelFarData THEN
  1975.             BEGIN
  1976.             fOptionFlags.Catenate('fD');
  1977.             fPascalOptions.Catenate(' -model farData');
  1978.             fCOptions.Catenate(' -model farData');
  1979.             fCPlusOptions.Catenate(' -model farData');
  1980.  
  1981.             CatenateToSourceOptionStrings(' -d qModelFarData=TRUE');
  1982.             END
  1983.         ELSE
  1984.             CatenateToSourceOptionStrings(' -d qModelFarData=FALSE');
  1985.  
  1986.         IF fModelFarCode | fModelFarData THEN
  1987.             BEGIN
  1988.             { these tools don't currently need to differentiate farcode and fardata }
  1989.             fAsmOptions.Catenate(' -model far');
  1990.             fLinkOptions.Catenate(' -model far');
  1991.             END;
  1992.  
  1993.         { Process separate objects }
  1994.         { Get basic name }
  1995.         IF fSeparateObjects THEN
  1996.             BEGIN
  1997.             IF NOT fRenameFlagsPairs.ValueAt(fOptionFlags.AsStr255, SeparateObjectsFolder) THEN
  1998.                 SeparateObjectsFolder := fOptionFlags.AsStr255;
  1999.             END
  2000.         ELSE
  2001.             BEGIN
  2002.             IF NOT IEGetEnv('MANoSeparateObjectsFolder', SeparateObjectsFolder) THEN
  2003.                 SeparateObjectsFolder := '';
  2004.             END;
  2005.  
  2006.         { Add the prefix }
  2007.         IF IEGetEnv('MASeparateObjectsPrefix', MASeparateObjectsPrefix) THEN
  2008.             SeparateObjectsFolder := concat(MASeparateObjectsPrefix, SeparateObjectsFolder,
  2009.                                             gDirectorySeparator);
  2010.  
  2011.         SetIE('SeparateObjectsFolder', SeparateObjectsFolder);
  2012.         fSeparateObjectsFolder := SeparateObjectsFolder;
  2013.  
  2014.         { Include Any unconditional options that we might want to force on unsuspecting
  2015.         tools but haven't the gall to include in the startup file.
  2016.         }
  2017.  
  2018.         { Rename some procedures so that they can be accessed from C++ }
  2019.         fLinkOptions.Catenate(' -ma __OBNEW=%_OBNEW -ma __PGM1=%_PGM1');
  2020.  
  2021.         { ensure that when this segment gets loaded it goes down as low in the heap as possible }
  2022.         fLinkOptions.Catenate(' -ra MAMain=resLocked');
  2023.  
  2024.         { output the results. }
  2025.         IF fTimes THEN
  2026.             WriteLn(fOutputFile^, 'SET XStartTime ', fStartDateTime);
  2027.         WriteLn(fOutputFile^, 'SET XTimes ', ord(fTimes));
  2028.         WriteLn(fOutputFile^, 'SET XRunAfterBuild ', ord(fRunAfterBuild));
  2029.  
  2030.         Write(fOutputFile^, 'SET AsmOptions "'); fAsmOptions.WriteToFile(fOutputFile);
  2031.         WriteLn(fOutputFile^, ' "');
  2032.         Write(fOutputFile^, 'SET COptions "'); fCOptions.WriteToFile(fOutputFile);
  2033.         WriteLn(fOutputFile^, ' "');
  2034.         Write(fOutputFile^, 'SET CPlusCPUOptions "'); fCPlusCPUOptions.WriteToFile(fOutputFile);
  2035.         WriteLn(fOutputFile^, ' "');
  2036.         Write(fOutputFile^, 'SET CPlusOptions "'); fCPlusOptions.WriteToFile(fOutputFile);
  2037.         WriteLn(fOutputFile^, ' "');
  2038.         Write(fOutputFile^, 'SET EchoOptions "'); fEchoOptions.WriteToFile(fOutputFile);
  2039.         WriteLn(fOutputFile^, ' "');
  2040.         Write(fOutputFile^, 'SET LibOptions "'); fLibOptions.WriteToFile(fOutputFile);
  2041.         WriteLn(fOutputFile^, ' "');
  2042.         Write(fOutputFile^, 'SET LinkOptions "'); fLinkOptions.WriteToFile(fOutputFile);
  2043.         WriteLn(fOutputFile^, ' "');
  2044.         Write(fOutputFile^, 'SET MakeOptions "'); fMakeOptions.WriteToFile(fOutputFile);
  2045.         WriteLn(fOutputFile^, ' "');
  2046.         Write(fOutputFile^, 'SET PascalCPUOptions "'); fPascalCPUOptions.WriteToFile(fOutputFile);
  2047.         WriteLn(fOutputFile^, ' "');
  2048.         Write(fOutputFile^, 'SET PascalOptions "'); fPascalOptions.WriteToFile(fOutputFile);
  2049.         WriteLn(fOutputFile^, ' "');
  2050.         Write(fOutputFile^, 'SET RezOptions "'); fRezOptions.WriteToFile(fOutputFile);
  2051.         WriteLn(fOutputFile^, ' "');
  2052.         Write(fOutputFile^, 'SET CreatorAndBundleOptions "');
  2053.         fCreatorAndBundleOptions.WriteToFile(fOutputFile);
  2054.         WriteLn(fOutputFile^, ' "');
  2055.  
  2056.         Write(fOutputFile^, 'SET XOptionFlags "'); fOptionFlags.WriteToFile(fOutputFile);
  2057.         WriteLn(fOutputFile^, '"');
  2058.  
  2059.         { Process autosave }
  2060.         IF fSaveBeforeBuild THEN
  2061.             BEGIN
  2062.             IF fProgress THEN
  2063.                 Echo('"AutoSaving…"');
  2064.             Execute('Save -a');
  2065.             END;
  2066.  
  2067.         { Remember the current directory }
  2068.         IF HGetVol(NIL, vRefNum, dirID) = noErr THEN
  2069.             fStartPath := PathNameFromDirID(dirID, vRefNum);
  2070.  
  2071.         { Make sure load files folder and separate objects folder exists for load files}
  2072.         IF IEGetEnv('MALoadFiles', MALoadFiles) THEN
  2073.             LoadFileDir := concat(MALoadFiles, fSeparateObjectsFolder)
  2074.         ELSE                                            { Punt }
  2075.             LoadFileDir := concat(MALoadFiles, fSeparateObjectsFolder);
  2076.         { Make sure the basic load files directory exists }
  2077.         IF (MALoadFiles <> '') & NOT Exists(MALoadFiles) & (DirCreate(0, 0, MALoadFiles, dirID) <>
  2078.            noErr) THEN
  2079.             BEGIN
  2080.             Echo('''###'' MABuild: Unable to create directory: "{MALoadFiles}"');
  2081.             Echo('MABuild of {XAppName} failed: `DATE`');
  2082.             Execute('{MAFailed}');
  2083.  
  2084.             IF fNoFail THEN
  2085.                 SetIE('XRunStatus', '1')
  2086.             ELSE
  2087.                 Execute('EXIT 1');
  2088.             END;
  2089.         { Make sure the load files directory that is specific to our build options exists }
  2090.         IF NOT Exists(LoadFileDir) & (DirCreate(0, 0, LoadFileDir, dirID) <> noErr) THEN
  2091.             BEGIN
  2092.             Echo(
  2093.                '''###'' MABuild: Unable to create directory: "{MALoadFiles}{SeparateObjectsFolder}"'
  2094.                  );
  2095.             Echo('MABuild of {XAppName} failed: `DATE`');
  2096.             Execute('{MAFailed}');
  2097.  
  2098.             IF fNoFail THEN
  2099.                 SetIE('XRunStatus', '1')
  2100.             ELSE
  2101.                 Execute('EXIT 1');
  2102.             END;
  2103.  
  2104.         { process each target in the list }
  2105.         DoAllTargets;
  2106.  
  2107.         { termination messages }
  2108.         IF fTimes THEN
  2109.             BEGIN
  2110.             Echo('" "');
  2111.             Echo('MABuild:   Elapsed time: `evaluate ∂`DATE -n∂` - {XStartTime}` seconds');
  2112.             END;
  2113.  
  2114.         Execute('IF "{XExitStatus}"');
  2115.         Execute('{MAFailed}');
  2116.         Execute('EXIT "{XExitStatus}"');
  2117.         Execute('END');
  2118.  
  2119.         IF fProgress THEN
  2120.             BEGIN
  2121.             Echo('Completion time for MABuild is `DATE`');
  2122.             Execute('{MADone}');
  2123.             END;
  2124.         END;
  2125. {--------------------------------------------------------------------------------------------------}
  2126. {$S TRes}
  2127.  
  2128.     BEGIN
  2129.     InitUPascalTool;
  2130.  
  2131.     New(gMABuildTool);
  2132.     gMABuildTool.IMABuildTool;
  2133.     gMABuildTool.Run;
  2134.     END.
  2135.